﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.HVAC;
using YArchitech.LIB;
using YArchitech.MEP;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	internal class DrawVRefrigerantPipe : IExternalCommand
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			UIApplication application = commandData.Application;
			UIDocument activeUIDocument = application.ActiveUIDocument;
			this.doc = activeUIDocument.Document;
			List<ViewType> viewTypes = YJKRevitTools.ListViewNeed(1);
			if (!YJKRevitTools.ViewCheck(activeUIDocument, viewTypes))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			Transaction transaction = null;
			string empty = string.Empty;
			Pipe pipe = null;
			if (DrawVRefrigerantPipe.hWndRevit == null)
			{
				DrawVRefrigerantPipe.hWndRevit = new YJKWindowHandle(Process.GetCurrentProcess().MainWindowHandle);
			}
			FormDrawVRefrigerantPipe formDrawVRefrigerantPipe = new FormDrawVRefrigerantPipe(this.doc);
			formDrawVRefrigerantPipe.Show(DrawVRefrigerantPipe.hWndRevit);
			int wMsg = 7;
			DrawVRefrigerantPipe.SendMessage(DrawVRefrigerantPipe.hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			try
			{
				RiserPipeOperation riserPipeOperation = new RiserPipeOperation();
				AuxiliaryFrameOperation afOperation = new AuxiliaryFrameOperation();
				new MarkOperation().SetActiveDocAllLoadedTags(this.doc, false);
				for (;;)
				{
					transaction = new Transaction(this.doc, "绘制冷媒立管");
					transaction.Start();
					using (this.drawJig = new DrawVRefrigerantJig(activeUIDocument, formDrawVRefrigerantPipe))
					{
						this.drawJig.length = formDrawVRefrigerantPipe.Configs.AssistLength;
						this.drawJig.angle = formDrawVRefrigerantPipe.Configs.AssistAngle;
						this.drawJig.isAuxiliaryFrame = formDrawVRefrigerantPipe.Configs.IsLocateAssist;
						this.drawJig.diameter = formDrawVRefrigerantPipe.Configs.PipeDiameterInfo;
						XYZ xyz = this.PickPoint(this.drawJig.PickAuxiliaryFramePoint("请选择布置冷媒立管的点"));
						if (xyz == null)
						{
							this.EndTransation(transaction, false);
							continue;
						}
						if (!formDrawVRefrigerantPipe.CheckUIData())
						{
							this.EndTransation(transaction, false);
							continue;
						}
						double num;
						double num2;
						if (!formDrawVRefrigerantPipe.Configs.IsRelative)
						{
							num = double.Parse(formDrawVRefrigerantPipe.Configs.BottomLevel) / 304.8;
							num2 = double.Parse(formDrawVRefrigerantPipe.Configs.TopLevel) / 304.8;
						}
						else
						{
							num = double.Parse(formDrawVRefrigerantPipe.Configs.StartOffset) / 304.8 + this.GetLevelOffset(formDrawVRefrigerantPipe.Configs.StartReference);
							num2 = double.Parse(formDrawVRefrigerantPipe.Configs.EndOffset) / 304.8 + this.GetLevelOffset(formDrawVRefrigerantPipe.Configs.EndReference);
						}
						if (Math.Abs(num - num2) < 0.032808398950131233)
						{
							YJKMessageBox.Show("冷媒立管起始点相距太近，不能小于10mm！", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
							this.EndTransation(transaction, false);
							continue;
						}
						riserPipeOperation.CreateAuxiliaryFrame(formDrawVRefrigerantPipe.Configs.IsLocateAssist, activeUIDocument, xyz, this.drawJig.length, this.drawJig.angle, afOperation);
						PipeType pipeType = this.CheckPipeType(this.doc);
						if (pipeType == null)
						{
							pipeType = new OperateSegmentFitting(this.doc).CreatHYPipeTypeByName(this.pipeTypeName);
							this.ChangeFirstRuleFitting(pipeType, this.doc);
						}
						PipingTypeInfo pipingInfo = this.GetPipingInfo(formDrawVRefrigerantPipe.Configs.PipeTypeName);
						PipingSystemType pipingSystemType = this.CreatePipingSystemType(this.doc, pipingInfo);
						double pipeDiameterInfo = formDrawVRefrigerantPipe.Configs.PipeDiameterInfo;
						pipe = this.DrawRiserPipe(xyz.X, xyz.Y, num, num2, this.doc, pipeType, pipeDiameterInfo, pipingSystemType, "");
						if (pipe == null)
						{
							continue;
						}
						if (formDrawVRefrigerantPipe.Configs.IsIntegratedPipe)
						{
							IDictionary<string, double> sharedParaDiameters = this.GetSharedParaDiameters(formDrawVRefrigerantPipe.Configs);
							this.CreateSharedParam(application);
							this.SetPipeSharedAttribute(pipe, sharedParaDiameters);
						}
						new DrawVRefrigerantMgr().SetMark(pipe, application, formDrawVRefrigerantPipe.Configs);
						this.drawJig.Dispose();
					}
					this.doc.Regenerate();
					transaction.Commit();
				}
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				if (pipe != null)
				{
					Parameter parameter = pipe.GetParameter("立管编号");
					if (parameter == null || string.IsNullOrEmpty(parameter.AsString()))
					{
						XYZ point = null;
						RiserPipeAndCenter riserPipeAndCenter = new RiserPipeAndCenter(pipe, point);
						if (Regex.IsMatch(formDrawVRefrigerantPipe.Configs.CustomNum, "^[0-9]+$"))
						{
							MarkRiserPipeUtility.SetRiserPipeParameters(application, riserPipeAndCenter.RiserPipe, "", formDrawVRefrigerantPipe.Configs.CustomNum, formDrawVRefrigerantPipe.Configs.IsCustom, false);
						}
					}
				}
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
				this.EndTransation(transaction, false);
				return Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				if (!formDrawVRefrigerantPipe.IsDisposed)
				{
					formDrawVRefrigerantPipe.Close();
				}
				if (this.drawJig != null)
				{
					this.drawJig.Dispose();
				}
				this.EndTransation(transaction, true);
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private PipingTypeInfo GetPipingInfo(string pipingType)
		{
			if (string.IsNullOrEmpty(pipingType))
			{
				return null;
			}
			return new ClassRefrigerantPipeCreateInfo().GetMultiPipeSetting(pipingType);
		}

		private PipeType CheckPipeType(Autodesk.Revit.DB.Document doc)
		{
			foreach (Element element in YJKElementFilter.GetElementByClass(typeof(PipeType), doc))
			{
				if (element.Name == this.pipeTypeName)
				{
					return element as PipeType;
				}
			}
			return null;
		}

		private void ChangeFirstRuleFitting(PipeType pipeType, Autodesk.Revit.DB.Document Doc)
		{
			for (int i = 0; i < 6; i++)
			{
				UnifiedModified.ClearSegmentFitting(pipeType, i);
			}
			try
			{
				string text = "";
				UnifiedModified.ClearSegmentFitting(pipeType, 10);
				PipeSegment pipeSegment = this.CreatePipeSegment(Doc);
				UnifiedModified.SetSegmentFitting(pipeType, 0, pipeSegment.Id, "管段");
				FamilySymbol familySymbol = YJKRevitTools.GetFamilySymbol("弯头_焊接_铜管", Doc);
				if (familySymbol == null)
				{
					familySymbol = YJKRevitTools.GetFamilySymbolByName("Fitting", "弯头_焊接_铜管", Doc, ref text);
				}
				UnifiedModified.SetSegmentFitting(pipeType, 1, familySymbol.Id, "弯头_焊接_铜管");
				FamilySymbol familySymbol2 = YJKRevitTools.GetFamilySymbol("等径三通_焊接_铜管", Doc);
				if (familySymbol2 == null)
				{
					familySymbol2 = YJKRevitTools.GetFamilySymbolByName("Fitting", "等径三通_焊接_铜管", Doc, ref text);
				}
				UnifiedModified.SetSegmentFitting(pipeType, 2, familySymbol2.Id, "等径三通_焊接_铜管");
				FamilySymbol familySymbol3 = YJKRevitTools.GetFamilySymbol("变径三通_焊接_铜管", Doc);
				if (familySymbol3 == null)
				{
					familySymbol3 = YJKRevitTools.GetFamilySymbolByName("Fitting", "变径三通_焊接_铜管", Doc, ref text);
				}
				UnifiedModified.SetSegmentFitting(pipeType, 2, familySymbol3.Id, "变径三通_焊接_铜管");
				FamilySymbol familySymbol4 = YJKRevitTools.GetFamilySymbol("四通_焊接_铜管", Doc);
				if (familySymbol4 == null)
				{
					familySymbol4 = YJKRevitTools.GetFamilySymbolByName("Fitting", "四通_焊接_铜管", Doc, ref text);
				}
				UnifiedModified.SetSegmentFitting(pipeType, 3, familySymbol4.Id, "四通_焊接_铜管");
				FamilySymbol familySymbol5 = YJKRevitTools.GetFamilySymbol("变径_焊接_铜管", Doc);
				if (familySymbol5 == null)
				{
					familySymbol5 = YJKRevitTools.GetFamilySymbolByName("Fitting", "变径_焊接_铜管", Doc, ref text);
				}
				UnifiedModified.SetSegmentFitting(pipeType, 4, familySymbol5.Id, "变径_焊接_铜管");
				FamilySymbol familySymbol6 = YJKRevitTools.GetFamilySymbol("管帽-焊接", Doc);
				if (familySymbol6 == null)
				{
					familySymbol6 = YJKRevitTools.GetFamilySymbolByName("Fitting", "管帽-焊接", Doc, ref text);
				}
				UnifiedModified.SetSegmentFitting(pipeType, 10, familySymbol6.Id, "管帽-焊接");
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		private PipeSegment CreatePipeSegment(Autodesk.Revit.DB.Document doc)
		{
			OperateSegmentFitting operateSegmentFitting = new OperateSegmentFitting(doc);
			HYMaterial hymaterial = new HYMaterial();
			hymaterial.Name = "铜";
			hymaterial.Roughness = 0.01;
			hymaterial.TubeType = 1;
			hymaterial.Segment = "铜";
			hymaterial.Schedule = "焊接";
			HYPipeSpecifications hypipeSpecifications = new HYPipeSpecifications();
			List<List<string>> pipeStorage = new ClassRefrigerantPipeCreateInfo().GetPipeStorage();
			new List<HYPipeSpecification>();
			int num = 0;
			foreach (List<string> list in pipeStorage)
			{
				hypipeSpecifications.Add(new HYPipeSpecification
				{
					DN = num,
					DN2 = list[0].ToDouble(0.0),
					Diameter = list[2].ToDouble(0.0),
					Thickness = list[2].ToDouble(0.0) - list[1].ToDouble(0.0)
				});
				num++;
			}
			hymaterial.Specifications = hypipeSpecifications;
			PipeSegment pipeSegment = operateSegmentFitting.CreatHYPipeSegment2(hymaterial);
			pipeSegment.Roughness = hymaterial.Roughness / 304.8;
			return pipeSegment;
		}

		private XYZ PickPoint(XYZ xyz)
		{
			if (this.drawJig == null)
			{
				return null;
			}
			if (this.drawJig.isAuxiliaryFrame)
			{
				double num = AssistFunc.mmToFeet(this.drawJig.length);
				if (this.drawJig.JigStage == DrawVRefrigerantJig.EStage.eLeftUpPt)
				{
					xyz = xyz.Add(num / 2.0 * this.drawJig.xVector).Add(-num / 2.0 * this.drawJig.yVector);
				}
				else if (this.drawJig.JigStage == DrawVRefrigerantJig.EStage.eLeftDownPt)
				{
					xyz = xyz.Add(num / 2.0 * this.drawJig.xVector).Add(num / 2.0 * this.drawJig.yVector);
				}
				else if (this.drawJig.JigStage == DrawVRefrigerantJig.EStage.eRightDownOper)
				{
					xyz = xyz.Add(-num / 2.0 * this.drawJig.xVector).Add(num / 2.0 * this.drawJig.yVector);
				}
				else if (this.drawJig.JigStage == DrawVRefrigerantJig.EStage.eRightUpOper)
				{
					xyz = xyz.Add(-num / 2.0 * this.drawJig.xVector).Add(-num / 2.0 * this.drawJig.yVector);
				}
			}
			return xyz;
		}

		public Pipe DrawRiserPipe(double x, double y, double zStart, double zEnd, Autodesk.Revit.DB.Document document, PipeType pipeType, double diameter, PipingSystemType pipingSystemType, string lable)
		{
			Level genLevel = document.ActiveView.GenLevel;
			XYZ start = new XYZ(x, y, zStart);
			XYZ end = new XYZ(x, y, zEnd);
			Pipe pipe = document.CreatHYPipe(pipingSystemType, pipeType, genLevel, start, end, diameter);
			pipe.get_Parameter(BuiltInParameter.DOOR_NUMBER).Set(lable);
			ElementTransformUtils.MoveElement(pipe.Document, pipe.Id, new XYZ(1E-05, 1E-05, 1E-05));
			ElementTransformUtils.MoveElement(pipe.Document, pipe.Id, -1.0 * new XYZ(1E-05, 1E-05, 1E-05));
			document.Regenerate();
			return pipe;
		}

		public PipingSystemType CreatePipingSystemType(Autodesk.Revit.DB.Document doc, PipingTypeInfo pipeTypeInfo)
		{
			PipingSystemType pipingSystemType = null;
			foreach (Element element in ((IEnumerable<Element>)YJKElementFilter.GetElementByClass(typeof(PipingSystemType), doc)))
			{
				if (element != null && element.Name == pipeTypeInfo.PipingType)
				{
					pipingSystemType = (element as PipingSystemType);
					break;
				}
			}
			if (pipingSystemType == null)
			{
				MEPSystemClassification mepsystemClassification = (MEPSystemClassification)Enum.Parse(typeof(MEPSystemClassification), AssistSystemType.GetPipeSystemTypeUS(pipeTypeInfo.PipingClassify), true);
				pipingSystemType = PipingSystemType.Create(doc, mepsystemClassification, pipeTypeInfo.PipingType);
			}
			pipingSystemType.get_Parameter(BuiltInParameter.RBS_SYSTEM_ABBREVIATION_PARAM).Set(pipeTypeInfo.Abb);
			if (pipeTypeInfo.LineColor != "默认")
			{
				pipingSystemType.LineColor = new Autodesk.Revit.DB.Color((byte)int.Parse(pipeTypeInfo.LineColor.Split(new char[]
				{
					' '
				}).ElementAt(1)), (byte)int.Parse(pipeTypeInfo.LineColor.Split(new char[]
				{
					' '
				}).ElementAt(2)), (byte)int.Parse(pipeTypeInfo.LineColor.Split(new char[]
				{
					' '
				}).ElementAt(3)));
			}
			if (pipeTypeInfo.LinePattern != "默认")
			{
				pipingSystemType.LinePatternId = LinePatternElement.GetLinePatternElementByName(doc, pipeTypeInfo.LinePattern).Id;
			}
			if (pipeTypeInfo.LineWeight != "默认")
			{
				pipingSystemType.LineWeight = int.Parse(pipeTypeInfo.LineWeight);
			}
			return pipingSystemType;
		}

		private void CreateSharedParam(UIApplication uiApp)
		{
			string pathName = Path.Combine(Product.DataLocation, "HYShared Parameters.txt");
			string gropeName = "管道参数";
			YJKRevitTools.SetInstanceParameter(uiApp, pathName, gropeName, new List<string>
			{
				"气管管径",
				"液管管径"
			}, (Autodesk.Revit.DB.BuiltInCategory)(-2008044), false);
		}

		private IDictionary<string, double> GetSharedParaDiameters(VPipeSetting pipeSetting)
		{
			if (pipeSetting == null)
			{
				return null;
			}
			return new Dictionary<string, double>
			{
				{
					"液管管径",
					Convert.ToDouble(pipeSetting.LiquidPipeDiameter)
				},
				{
					"气管管径",
					Convert.ToDouble(pipeSetting.GasPipeDiameter)
				}
			};
		}

		private void SetPipeSharedAttribute(Pipe pipe, IDictionary<string, double> diameterDic)
		{
			if (diameterDic == null || diameterDic.Count <= 0)
			{
				return;
			}
			if (diameterDic["气管管径"] > 0.0 && pipe.GetParameter("气管管径") != null)
			{
				pipe.GetParameter("气管管径").Set(diameterDic["气管管径"] / 304.8);
			}
			if (diameterDic["液管管径"] > 0.0 && pipe.GetParameter("液管管径") != null)
			{
				pipe.GetParameter("液管管径").Set(diameterDic["液管管径"] / 304.8);
			}
		}

		private void EndTransation(Transaction tran, bool beSure)
		{
			if (tran != null)
			{
				TransactionStatus status = tran.GetStatus();
				if ((int)status == 1)
				{
					if (beSure)
					{
						tran.Commit();
						return;
					}
					tran.RollBack();
					return;
				}
				else if ((int)status == 5)
				{
					tran.RollBack();
				}
			}
		}

		private double GetLevelOffset(string level)
		{
			double result = 0.0;
			if (string.IsNullOrEmpty(level))
			{
				return result;
			}
			return this.Get_Level(this.doc, level).ProjectElevation;
		}

		private Level Get_Level(Autodesk.Revit.DB.Document document, string levelName)
		{
			Level result = null;
			foreach (Element element in ((IEnumerable<Element>)YJKElementFilter.GetElementByClass(typeof(Level), document)))
			{
				if (element.Name == levelName)
				{
					result = (element as Level);
					break;
				}
			}
			return result;
		}

		public static YJKWindowHandle hWndRevit;

		private DrawVRefrigerantJig drawJig;

		private readonly string pipeTypeName = "铜管-焊接";

		private Document doc;
	}
}
